#  -*- coding: utf-8 -*-

from pymongo import UpdateOne,ASCENDING, DESCENDING
from monitor.base_monitor import BaseMonitor
from data.finance_report_crawler import FinanceReportCrawler
from data.data_module import DataModule
from util.stock_util import get_all_codes,get_all_indexes_date,calc_negative_diff_dates,calc_positive_diff_dates,multi_computer,get_code_name,\
    judge_code_trading_date,get_diff_dates
from util.database import DB_CONN,ts_pro
import time
import pandas as pd
from datetime import datetime, timedelta
from sklearn import linear_model
from factor.factor_module import FactorModule
import numpy as np

"""
实现某一时期最佳板块的计算
"""


class MainIndexMonitor(BaseMonitor):
    def __init__(self):
        BaseMonitor.__init__(self, name='main_index')
        main_index_dict ={
            '000016':"上证50",
            '000300':"沪深300",
            '000905':"中证500",
            '999999':"上证指数",
            '399001':"深圳指数",
            '399005':"中小板指",
            '399006':"创业板指"}
        dm = DataModule()
        fm = FactorModule()

    def gen_ma_info(self,index:str,date)->dict:
        ma_info_dict = dict()
        trade_date = judge_code_trading_date(index,is_index=True,date=date)
        #最近一周的数据用来拟合斜率
        beg_date = calc_negative_diff_dates(index,is_index=True,date=trade_date,delta_days=-4)
        #recent_k_data = self.dm.get_k_data(index,index=True,autype=None,period='D', begin_date=beg_date, end_date=trade_date)
        #recent_k_data.set_index(['date'], inplace=True)
        hfq_ma_df = self.fm.get_single_stock_factors(index, "hfq_ma", True, beg_date, trade_date)
        hfq_ma_df.set_index(['date'], inplace=True)

        clf = linear_model.LinearRegression()
        clf.fit(np.arange(5).reshape(-1, 1), hfq_ma_df['ma20'].loc[beg_date:trade_date])
        k_20 = clf.coef_
        clf.fit(np.arange(5).reshape(-1, 1), hfq_ma_df['ma99'].loc[beg_date:trade_date])
        k_99 = clf.coef_
        ma_info_dict ={
            'ma20':hfq_ma_df.loc[trade_date]['ma20'],
            'ma99':hfq_ma_df.loc[trade_date]['ma99'],
            'k_20':k_20,
            'k_99':k_99,
        }
        return ma_info_dict

    def judge_k2(self,k2):
        if k2 > 0.1:
            type = 1
        elif k2 < 0.1:
            type = 2
        else:
            type = 3
        return type

    def judge_k1(self,k1,k2):
        if k1 > 0.1:
            type = 0 + self.judge_k2(k2)
        elif k1 < 0.1:
            type = 3 + self.judge_k2(k2)
        else:
            type = 6 + self.judge_k2(k2)
        return type

    def separate_issues_for_index(self,ma_info):
        ma20 = ma_info['ma20']
        ma99 = ma_info['ma99']
        k_20 = ma_info['k_20']
        k_99 = ma_info['k_99']
        if ma20 >= ma99:
            type = self.judge_k1(k_20,k_99)
        else:
            type = 9 + self.judge_k1(k_20,k_99)
        return type

    def calc_change_rate_when_change_type(self,index,type_date,next_type_date):
        #result_dict = dict()
        buy_date = calc_positive_diff_dates(code=index, date=type_date, delta_days=1)
        sell_date = calc_positive_diff_dates(code=index, date=next_type_date, delta_days=1)

        code_df = self.dm.get_k_data(index, index=True, autype=None, begin_date=buy_date, end_date=sell_date)
        if code_df.index.size == 0:
            return None
        code_df.set_index(['date'], inplace=True)
        # 买入、卖出日的开盘价
        beg_open = code_df.loc[buy_date]['open']
        end_open = code_df.loc[sell_date]['open']

        change_rate = round(100 * (end_open - beg_open) / beg_open, 2)
        return change_rate

    def monitoring(self, begin_date, end_date):
        """
        计算指定时间范围内板块涨幅排名
        """
        start_time = time.time()
        dm = DataModule()

        if begin_date is None:
            begin_date = "1990-12-19"

        #begin_date存在的指数，end_date一定存在
        codes = get_all_indexes_date(begin_date)
        codes_count = len(codes)
        block_rank_date_df = pd.DataFrame(columns=["relative_ratio","name","rank"],index=codes)

        i = 0
        #找到begin_date和end_date当日所有指数数据，以code为索引
        begin_df = dm.get_one_day_k_data(is_index=True, autype=None, period='D', date=begin_date)
        if begin_df.index.size > 0:
            begin_df.set_index(['code'], 1, inplace=True)

        end_df = dm.get_one_day_k_data(is_index=True, autype=None, period='D', date=end_date)
        if end_df.index.size > 0:
            end_df.set_index(['code'], 1, inplace=True)


        for code in codes:
            begin_close =begin_df.loc[code]['close']
            end_close = end_df.loc[code]['close']

            block_rank_date_df.loc[code]["relative_ratio"] = round(100 * (end_close - begin_close) / begin_close, 2)
            block_rank_date_df.loc[code]["name"] = get_code_name(code,True)


        # 从大到小计算排名
        block_rank_date_df['rank'] = block_rank_date_df["relative_ratio"].rank(ascending=False)
        #按排名重新排序
        block_rank_date_df.sort_values(by="rank",inplace=True)
        block_rank_date_df.to_csv(("From%sto%s_blockrank.csv" %(begin_date,end_date)),encoding='utf_8_sig')
        print(block_rank_date_df)

if __name__ == '__main__':
    # 执行因子的提取任务
    #hfq =HfqMAFactor()

    MainIndexMonitor().monitoring('2019-08-06', '2019-09-04')
